package top.lingkang.finalgateway.utils;

import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Date;

import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * @author lingkang
 * @create by 2024/4/26 17:36
 */
@Slf4j
public class HttpUtils {
    private static final String str404 = "{\"code\":1,\"msg\":\"final-gateway 404 not found\"}";
    private static final String str500 = "{\"code\":1,\"msg\":\"final-gateway 500 error\"}";
    private static final String errNotSupported = "{\"code\":1,\"msg\":\"不支持的请求类型\"}";
    private static final String uploadContentTooLarge = "{\"code\":1,\"msg\":\"Failed to send a 413 Request Entity Too Large\"}";

    public static void sendString(String context, int code, ChannelHandlerContext ctx) {
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(code),
                Unpooled.copiedBuffer(context.getBytes())
        );
        // 设置响应头部
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=utf-8");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());

        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

    public static FullHttpResponse getResponse(String context, int code) {
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(code),
                Unpooled.copiedBuffer(context.getBytes())
        );
        // 设置响应头部
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=utf-8");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, context.length());
        return response;
    }

    public static void return403Forbidden(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(getResponse("forbidden access", 403)).addListener(ChannelFutureListener.CLOSE);
        /*String res = "HTTP/1.1 403 Forbidden\n" +
                "Content-Type: text/plain;charset=utf-8\n" +
                "Content-Type: 16\n" +
                "\r\n" +
                "forbidden access";*/
        /*ctx.writeAndFlush(Unpooled.wrappedBuffer(res.getBytes(StandardCharsets.UTF_8)))
                .addListener(ChannelFutureListener.CLOSE);*/
        /*ctx.writeAndFlush(new DefaultHttpContent(Unpooled.wrappedBuffer(res.getBytes(StandardCharsets.UTF_8))))
                .addListener(ChannelFutureListener.CLOSE);*/
    }

    public static void return404Json(ChannelHandlerContext ctx) {
        FullHttpResponse response = HttpUtils.getResponse(str404, 404);
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

    public static void return505Json(ChannelHandlerContext ctx) {
        FullHttpResponse response = HttpUtils.getResponse(str500, 500);
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

    public static void returnNotSupported(ChannelHandlerContext ctx) {
        FullHttpResponse response = HttpUtils.getResponse(errNotSupported, 500);
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

    public static void returnTooLarge(ChannelHandlerContext ctx, int maxSize) {
        FullHttpResponse response = HttpUtils.getResponse(uploadContentTooLarge, 413);
        response.headers().set("error", "413 Request Entity Too Large. max " + maxSize + " byte");
        ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    log.debug("Failed to send a 413 Request Entity Too Large.", future.cause());
                    ctx.close();
                }
            }
        });
    }

    public static void closeHttpWebsocket(ChannelHandlerContext context, String msg) {
        FullHttpResponse response = new DefaultFullHttpResponse(
                HTTP_1_1, HttpResponseStatus.NOT_FOUND, Unpooled.wrappedBuffer(msg.getBytes()));
        response.headers().set(new DefaultHttpHeaders()
                .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE)
                .set("keep-alive", "timeout=60")
                .set(HttpHeaderNames.DATE, new Date()));
        context.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

    public static String getIpv4Address(Channel channel) {
        // 获取远程地址
        InetSocketAddress remoteAddress = (InetSocketAddress) channel.remoteAddress();
        return getIpv4Address(remoteAddress);
    }

    public static String getIpv4Address(InetSocketAddress address) {
        InetAddress inetAddress = address.getAddress();
        if (inetAddress instanceof java.net.Inet4Address)
            return inetAddress.getHostAddress();
        else
            return "127.0.0.1";
    }
}
